//
//  header.h
//  
//
//  Created by Yun Zhang on 3/30/12.
//  Copyright (c) 2012 Columbia University. All rights reserved.
//

#ifndef _header_h
#define _header_h
#include <vector>
#include <string>
#include <iostream>
using namespace std;

class node{
public:
    string name;
    node(string name1){name = name1;}
    vector<node*> nodelist;
    virtual void print() = 0;

   
};
class start_node:public node{
    node *inc;
    node *prog;
public:
    start_node(node *inc1, node *prog1):node("start_node"){
        inc = inc1;
        prog = prog1;
    }
    virtual void print();
};

class terminal:public node{
    string value;
    double num_value;
public:
    terminal(string value1):node("string_terminal"){
        value = value1;
    }
    terminal(double num_value1):node("num_terminal"){
        num_value = num_value1;
        value = "";
    }
    virtual void print();
//    virtual void print();
//    ~terminal();
};

class array_func_type:public node{
    node *type;
    node *expr_para;
public:
    array_func_type(node *t, node *e_p):node("array_or_func_type"){
        type = t;
        expr_para = e_p;
    }
    virtual void print();
    
};

class unary_stmt:public node{
    string stmt_name;
    node *p;
public:
    unary_stmt(string name1, node *p1):node("unary_stmt"){
        stmt_name = name1;
        p = p1;
    } 
    virtual void print();
};

class assign_node:public node{
    string op;
    node *left;
    node *right;
public:
    assign_node(string op1, node *left1, node *right1):node("assign_node"){
        op = op1;
        left = left1;
        right = right1;
    }
    virtual void print();
};

class if_stmt:public node{
    node *condition;
    node *stmt1;
    node *stmt2;
public:
    if_stmt(node *con, node *st1):node("if_stmt"){
        condition = con;
        stmt1 = st1;
    }
    if_stmt(node *con, node *st1, node *st2):node("if_stmt"){
        condition = con;
        stmt1 = st1;
        stmt2 = st2;
    }
    virtual void print();
};
class for_stmt:public node{
    node *left_value;
    node *expr1;
    node *expr2;
    node *stmt;
public:
    for_stmt(node *l1, node *e1, node *e2, node *st):node("for_stmt"){
        left_value = l1;
        expr1 = e1; 
        expr2 = e2;
        stmt = st;
    }
    virtual void print();
};

class list:public node{
    string list_name;
    
public:
    //vector<node*> nodelist;
    list(string list_name1):node("list")
    {
        list_name = list_name1;
    }
    virtual void print();
};
class var_decl:public node{
    node *type;
    node *para;
public:
    var_decl(node *t1, node *p1):node("var_decl"){
        type = t1;
        para = t1;
    }
    virtual void print();
};

class const_expr:public node{
    string op;
    node *left;
    node *right;
public:
    const_expr(string op1, node *left1, node *right1):node("const_expr"){
        op = op1;
        left = left1;
        right = right1;
    }
    virtual void print();
};
class unary_expr:public node{
    node *op;
    node *expr;
public:
    unary_expr(node *op1, node *expr1):node("unary_expr"){
        op = op1;
        expr = expr1;
    }
    virtual void print();
};

class unary_direct_expr:public node{
    node *unary_expr;
    node *const_expr;
public:
    unary_direct_expr(node *u, node *c):node("unary_direct_expr"){
        unary_expr = u;
        const_expr = c;
    }
    virtual void print();
};

class para_declaration:public node{
    node *type;
    node *terminal;
    node *expr;
public:
    para_declaration(node *t, node *term, node *e):node("para_declaration"){
        type = t;
        terminal = term;
        expr = e;
    }
    virtual void print();
};
class func_def:public node{
    node *id;
    node *type;
    node *para_list;
    node *stmt;
public:
    func_def(node *id1, node *t1, node *p1, node *st):node("func_def"){
        id = id1;
        type = t1;
        para_list = p1;
        stmt = st;
    }
    virtual void print();
    
};


class func_call:public node{
    node *unary_expr;
    node *parameter_list;
public:
    func_call(node *u, node *p):node("func_call"){
        unary_expr = u;
        parameter_list = p;
    }
    virtual void print();
};
















#endif
